#ifndef BASE_INCLUDE_FILE_MISC_H
#define BASE_INCLUDE_FILE_MISC_H

#include "conf.h"
//---------------------------------------------------------
// general macros
//---------------------------------------------------------
#define _INTERNAL_JOIN_BASE_(a, b)			a##b
#define _INTERNAL_JOIN_IMPL_(a, b)			_INTERNAL_JOIN_BASE_(a, b)

#define BASE_TOKEN_JOIN(a, b)				_INTERNAL_JOIN_IMPL_(a, b)
#define BASE_TOKEN_APPEND_SUFFIX(a, b)		BASE_TOKEN_JOIN(b, a)
#define BASE_TOKEN_APPEND_PREFIX(a, b)		BASE_TOKEN_JOIN(a, b)

#if defined (_MSC_VER)
#	define BASE_TOKEN_MAKE_UNIQUE(base)		BASE_TOKEN_JOIN(base, __LINE__)//BASE_TOKEN_JOIN(base, __COUNTER__)
#elif defined (__GNUC__)
#	define BASE_TOKEN_MAKE_UNIQUE(base)		BASE_TOKEN_JOIN(base, __LINE__)
#endif

//---------------------------------------------------------
// static initialize scope
//---------------------------------------------------------
#define BASE_BLOCK_BEGIN(name)				struct name { name () {
#define BASE_BLOCK_END						}}

#define BASE_INITIALIZER_BEGIN				BASE_BLOCK_BEGIN(BASE_TOKEN_MAKE_UNIQUE(_private_initializer_))
#define BASE_INITIALIZER_END				BASE_BLOCK_END BASE_TOKEN_MAKE_UNIQUE(_private_initializer_);

//---------------------------------------------------------
// byte-order swap utility
//---------------------------------------------------------
#ifdef _MSC_VER
#	include <stdlib.h>
#	pragma intrinsic(_lrotr, _lrotl)
#	define BASE_ROTR(x, n)	_lrotr((x), (n))
#	define BASE_ROTL(x, n)	_lrotl((x), (n))
#else
#	define BASE_ROTR(x, n)	(((x) >> (n)) | ((x) << (32 - (n))))
#	define BASE_ROTL(x, n)	(((x) << (n)) | ((x) >> (32 - (n))))
#endif

#define BASE_BSWAP16(x)		((((x)&0xFF)<<8)|(((x)&0xFF00)>>8))
#define BASE_BSWAP32(x)		(BASE_ROTL(x, 8) & 0x00ff00ff | BASE_ROTR(x, 8) & 0xff00ff00)
#define BASE_BSWAP64(x)		(((uint64_t)BASE_BSWAP32(uint32_t(x)&0xFFFFFFFF)<<32)|(BASE_BSWAP32((x)>>32)&0xFFFFFFFF))


#if defined(BIG_ENDIAN)
	inline int16_t SwapEndian(int16_t n)	{ return BASE_BSWAP16(n); }
	inline int32_t SwapEndian(int32_t n)	{ return BASE_BSWAP32(n); }
	inline int64_t SwapEndian(int64_t n)	{ return BASE_BSWAP64(n); }
	inline uint16_t SwapEndian(uint16_t n)	{ return BASE_BSWAP16(n); }
	inline uint32_t SwapEndian(uint32_t n)	{ return BASE_BSWAP32(n); }
	inline uint64_t SwapEndian(uint64_t n)	{ return BASE_BSWAP64(n); }
#else
	inline int16_t SwapEndian(int16_t n)	{ return (n); }
	inline int32_t SwapEndian(int32_t n)	{ return (n); }
	inline int64_t SwapEndian(int64_t n)	{ return (n); }
	inline uint16_t SwapEndian(uint16_t n)	{ return (n); }
	inline uint32_t SwapEndian(uint32_t n)	{ return (n); }
	inline uint64_t SwapEndian(uint64_t n)	{ return (n); }
	//#define SwapEndian(n) (n)
#endif

//---------------------------------------------------------
#include <cassert>
#define ASSERT	assert

//---------------------------------------------------------
#endif	//#ifndef BASE_INCLUDE_FILE_MISC_H


